//! simink 通用的错误代码
//!
//! 理论上每个模块都有自己独立的错误代码, 但是实际情况是错误代码并不能相互独立,
//! 典型的是 monitor 和 dfs, 当执行命令时,
//! 返回的错误代码不仅仅是监视器的错误代码也可能是 dfs 的错误代码,
//! 当强制独立错误代码, smp 控制协议结果返回将会非常混乱, 基于此原因在这里将所有错误统一.

use std::fmt::Display;

use serde::{Deserialize, Serialize};

/// 通用返回结果定义
pub type SmkResult<T> = Result<T, SmkError>;

/// 通用错误代码定义
#[derive(Serialize, Deserialize)]
#[derive(Debug, PartialEq, Eq)]
pub enum SmkError {
    /// 命令已经存在
    ExistCommand,
    /// 命令不存在
    NoCommand,
    /// 不符合定义的参数类型或者格式
    InvalidArgsType,
    /// 无效的 smp 控制协议格式
    InvalidProtocol,
    /// 不允许使用 smp 控制协议
    PermProtocol,
    /// 操作不允许
    PermOperation,
    /// 没有这个文件
    NoFile,
    /// 没有这个文件夹
    NoDir,
    /// 文件存在
    ExistFile,
    /// 文件夹存在
    ExistDir,
    /// 是一个文件
    IsFile,
    /// 是一个文件夹
    IsDir,
    /// 无效参数
    InvalidArgs,
    /// 非法 seek
    IllegalSeek,
    /// 非法 fcntl
    IllegalFcntl,
    /// 不可读
    NoRead,
    /// 不可写
    NoWrite,
    /// 不能 seek
    NoSeek,
    /// 不能 fcntl
    NoFcntl,
    /// 节点繁忙
    BusyInode,
    /// 文件夹不为空
    DirNoEmpty,
    /// 没有这个文件或文件夹
    NoEnt,
    /// 对象已经存在
    ExistObj,
    /// 对象不存在
    NoExistObj,
    /// 本机系统返回错误
    SystemError,
}

impl Display for SmkError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let error = match self {
            Self::ExistCommand => "命令已经存在",
            Self::NoCommand => "命令不存在",
            Self::InvalidArgsType => "不符合定义的参数类型或者格式",
            Self::InvalidProtocol => "无效的 smp 控制协议格式",
            Self::PermProtocol => "不允许使用 smp 控制协议",
            Self::PermOperation => "操作不允许",
            Self::NoFile => "没有这个文件",
            Self::NoDir => "没有这个文件夹",
            Self::ExistFile => "文件存在",
            Self::ExistDir => "文件夹存在",
            Self::IsFile => "是一个文件",
            Self::IsDir => "是一个文件夹",
            Self::InvalidArgs => "无效参数",
            Self::IllegalSeek => "非法seek",
            Self::IllegalFcntl => "非法fcntl",
            Self::NoRead => "不可读",
            Self::NoWrite => "不可写",
            Self::NoSeek => "不能seek",
            Self::NoFcntl => "不能fcntl",
            Self::BusyInode => "节点繁忙",
            Self::DirNoEmpty => "文件夹不为空",
            Self::NoEnt => "没有这个文件或文件夹",
            Self::ExistObj => "对象已经存在",
            Self::NoExistObj => "对象不存在",
            Self::SystemError => "本机系统返回错误",
        };
        write!(f, "{}", error)
    }
}
